package com.shimao.celnet.payment.controller.api;

import com.baiwang.bop.respose.entity.InvoiceQueryResponse;
import com.shimao.celnet.payment.common.exception.BaseException;
import com.shimao.celnet.payment.controller.apinotcheck.CallOut_invOpenOutController;
import com.shimao.celnet.payment.controller.apinotcheck.CallOut_invOpenRetInfoOutController;
import com.shimao.celnet.payment.controller.apinotcheck.CallOut_invPdfOutController;
import com.shimao.celnet.payment.controller.apinotcheck.CallOut_invoiceQueryOutController;
import com.shimao.celnet.payment.model.PInvoiceBlue;
import com.shimao.celnet.payment.model.PInvoiceBlueDetail;
import com.shimao.celnet.payment.model.request.CallIn_OutInvOpenBuleDetailReqIn;
import com.shimao.celnet.payment.model.request.CallIn_OutInvOpenBuleReqIn;
import com.shimao.celnet.payment.model.response.ErrorInfoEnum;
import com.shimao.celnet.payment.model.response.ResponseJson;
import com.shimao.celnet.payment.service.BInvoiceCompanyService;
import com.shimao.celnet.payment.service.PInvoiceBlueService;
import com.shimao.celnet.payment.service.SCodeNameService;
import com.shimao.celnet.payment.util.FinalUtil;
import com.shimao.celnet.payment.util.MyDateUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import net.sf.json.JSONObject;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;


/**
 * 外部系统 → 支付系统，数据：请求开蓝票信息
 * 返回给外部系统receiptGuid，
 * 2017/12/14
 * stan
 */
@RestController
@RequestMapping(value = "/invoice")
@Api("接口：pay-160(蓝票)-外部开票申请<outInvOpenBuleReq> 外部系统 → 支付系统，数据：开票详细信息")
public class CallIn_outInvOpenBuleReqInController {
    protected Logger logger = Logger.getLogger(this.getClass());

    @Autowired//开票申请
    private PInvoiceBlueService pInvoiceBlueService;

    @Autowired
    private CallOut_invPdfOutController callOut_invPdfOutController;
    @Autowired//参数表
    private SCodeNameService sCodeNameService;

    @Autowired//开票公司
    private BInvoiceCompanyService bInvoiceCompanyService;

    @Autowired//开具发票接口
    private CallOut_invOpenOutController callOut_invOpenOutController;

    @Autowired
    private CallOut_invoiceQueryOutController callOut_invoiceQueryOutController;//根据发票信息查询百望那边响应回来的发票信息

    @Autowired
    private CallOut_invOpenRetInfoOutController callOut_invOpenRetInfoOutController;//通过百望响应给我们的数据构建蓝票和红票信息以JSONObject返回给调用者


    /**
     * 外部系统开票申请
     *
     * @param requestJson
     * @throws BaseException
     */
    @ApiOperation("获取外部请求开票数据")
    @RequestMapping(value = "/invReqBlue", method = RequestMethod.POST)
    public String OutInvOpenBuleReqIn(@RequestBody @Valid CallIn_OutInvOpenBuleReqIn requestJson, BindingResult result) throws IOException, ParseException, BaseException {
        ResponseJson retJson = new ResponseJson(ErrorInfoEnum.SUCCESS, "");
        try {
            logger.info("pay-160-外部开票申请<outInvOpenBuleReq>请求JSON:" + requestJson.toString());
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            //通过valid验证
            if (result.hasErrors()) {
                for (FieldError error : result.getFieldErrors()) {
                    logger.debug("缺少必要参数：" + error.getDefaultMessage());
                    retJson = new ResponseJson(ErrorInfoEnum.NOT_PARAMS, error.getDefaultMessage());
                    return retJson.toString();
                }
            }
            String appKey = request.getHeader(FinalUtil.HEADER_APP_KEY);//获取header中的app_key
            String interfaceId = request.getHeader(FinalUtil.HEADER_INTERFACE_ID);//获取header中的interface_id
            logger.info("应用编号：" + appKey);
            logger.info("接口编号：" + interfaceId);
            PInvoiceBlue pInvoiceBlue = new PInvoiceBlue();//定义开蓝票记录对象
            String receiptGuid = pInvoiceBlueService.getGuid();//生成开票记录guid
            retJson.addBody("receiptGuid", receiptGuid);//将开票记录guid返回给请求的外部系统
            pInvoiceBlue.setGuid(receiptGuid);
            pInvoiceBlue.setImmediatelyFlg(requestJson.getImmediatelyFlg());//立即开票标识
            pInvoiceBlue.setBusinessType(requestJson.getBusinessType());//业务类型
            pInvoiceBlue.setEstateSfGuid(requestJson.getEstateId());//小区sfid
            // pInvoiceBlue.setEstatename(requestJson.getEstateName());//小区名称
            pInvoiceBlue.setDeviceType(requestJson.getDeviceType());//设备类型deviceType
            pInvoiceBlue.setLimitAccount(requestJson.getLimitAccount());//开票限额
            pInvoiceBlue.setInvoiceTypeCode(requestJson.getInvoiceTypeCode());//发票种类
            pInvoiceBlue.setInvoiceYerminalCode(requestJson.getInvoiceTerminalCode());//开票点编码
            pInvoiceBlue.setInvoiceSpecialMark(requestJson.getInvoiceSpecialMark());//特殊票种标记
            //销方单位税号:：根据小区sfguid从开票公司表中取得
            if(bInvoiceCompanyService.getCompanyByEstateSFGuid(requestJson.getEstateId())==null){
                return new ResponseJson(ErrorInfoEnum.ERROR_PARAMS,"世茂无此小区："+requestJson.getEstateId()).toString();
            }
            //取的销方税号
            pInvoiceBlue.setSellerTaxNo(bInvoiceCompanyService.getCompanyByEstateSFGuid(requestJson.getEstateId()).getSellerTaxNo());
            pInvoiceBlue.setBuyerName(requestJson.getBuyerName());//购方单位名称
            pInvoiceBlue.setBuyerBankAccount(requestJson.getBuyerBankAccount());// 购方开户行及账号，专票必填
            pInvoiceBlue.setBuyerTaxNo(requestJson.getBuyerTaxNo());//  * 购方单位税号
            pInvoiceBlue.setBuyerAddressPhone(requestJson.getBuyerAddressPhone());// 购方地址及电话，专票必填，即时开票标识为1时必须
            pInvoiceBlue.setBuyerEmail(requestJson.getBuyerEmail());//购方邮箱
            pInvoiceBlue.setBuyerPhone(requestJson.getBuyerPhone());//购方电话
            pInvoiceBlue.setDrawer(requestJson.getDrawer());//开票人
            pInvoiceBlue.setChecker(requestJson.getChecker());
            pInvoiceBlue.setPayee(requestJson.getPayee());
            pInvoiceBlue.setInvoiceListMark(requestJson.getInvoiceListMark());//清单标志
            pInvoiceBlue.setTaxationMode(requestJson.getTaxationMode());//征税方式
            pInvoiceBlue.setDeductibleAmount(requestJson.getDeductibleAmount());//扣除金额
            pInvoiceBlue.setInvoiceTotalPriceTax(requestJson.getInvoiceTotalPriceTax());//开票金额合计
            pInvoiceBlue.setInvoiceStartTime(MyDateUtil.getReportFileStrDate());//开票开始时间
            pInvoiceBlue.setInvoiceTotalTax(requestJson.getInvoiceTotalTax());// 税额合计
            pInvoiceBlue.setInvoiceTotalPrice(requestJson.getInvoiceTotalPrice()); //合计金额 不含税
            pInvoiceBlue.setTaxDiskNo(requestJson.getTaxDiskNo());//税控盘-编号
            pInvoiceBlue.setTaxDiskKey(requestJson.getTaxDiskKey());//税控盘-口令
            pInvoiceBlue.setTaxDiskPassword(requestJson.getTaxDiskPassword());//税控盘-密码
            pInvoiceBlue.setRemarks(requestJson.getRemarks());//备注
            pInvoiceBlue.setInvoiceType(FinalUtil.INVOICE_BULE);//蓝票
            pInvoiceBlue.setInvlidFlg(FinalUtil.INVLID_FLG_DEFAULT);//作废标记默认为；未作废 0 作废：1
            pInvoiceBlue.setInvoicePrintFlg(FinalUtil.INVLID_FLG_PRINT);//打印标记默认为：0未打印  1打印
            pInvoiceBlue.setInvoiceStatus(FinalUtil.INVOICE_STATUS_1);//发票状态；外部请求开票
            pInvoiceBlue.setUserName(requestJson.getUserName());//业主名
            pInvoiceBlue.setHouseName(requestJson.getHouseName());//房源名称
            pInvoiceBlue.setHouseSfId(requestJson.getHouseSfId());//房源sfid
            //serialNo开票流水号；不在接口中传递，支付系统自己生成
            pInvoiceBlue.setSerialNo(sCodeNameService.getInvoiceSellerNumber());
            pInvoiceBlue.setAppKey(appKey);  //外部系统来源
            pInvoiceBlue.setInterfaceId(interfaceId);//外部系统请求接口
            pInvoiceBlue.setRedFlg(FinalUtil.INVOICE_RED_FLG);//是否红冲 （1 未红冲）（ 2 红冲）
            pInvoiceBlue.setIsPush("0");   //是否推送标示，0：未推送，1：已推送
            //开票明细
            List<CallIn_OutInvOpenBuleDetailReqIn> invoiceReqInDetailsList = requestJson.getInvoiceDetailsList();
            List<PInvoiceBlueDetail> pInvoiceBlueDetailList = new ArrayList<PInvoiceBlueDetail>();
            //对开票记录的明细list遍历
            for (CallIn_OutInvOpenBuleDetailReqIn invoiceDetail : invoiceReqInDetailsList) {
                PInvoiceBlueDetail pInvoiceBlueDetail = new PInvoiceBlueDetail();//定义开票记录明细对象
                pInvoiceBlueDetail.setGoodsLineNo(invoiceDetail.getGoodsLineNo());//明细行号
                pInvoiceBlueDetail.setExsysDetailId(invoiceDetail.getExsysDetailID());//外部明细id
                pInvoiceBlueDetail.setGoodsLineNature(invoiceDetail.getGoodsLineNature());//发票行性质
                pInvoiceBlueDetail.setGoodsLineNo(invoiceDetail.getGoodsLineNo());//开票明细记录 发票行号
                pInvoiceBlueDetail.setGoodsLineNature(invoiceDetail.getGoodsLineNature());//开票明细记录 发票行性质
                pInvoiceBlueDetail.setGoodsCode(invoiceDetail.getGoodsCode());///开票明细记录 国税商品编码
                pInvoiceBlueDetail.setGoodsExtendCode(invoiceDetail.getGoodsExtendCode());///开票明细记录 自定义商品编码
                pInvoiceBlueDetail.setGoodsName(invoiceDetail.getGoodsName());//开票明细记录 商品名称
                pInvoiceBlueDetail.setGoodsSpecification(invoiceDetail.getGoodsSpecification());//开票明细记录 型号
                pInvoiceBlueDetail.setGoodsUnit(invoiceDetail.getGoodsUnit());//开票明细记录 单位
                pInvoiceBlueDetail.setGoodsQuantity(invoiceDetail.getGoodsQuantity());//开票明细记录 数量
                pInvoiceBlueDetail.setGoodsPrice(invoiceDetail.getGoodsPrice());//开票明细记录 单价
                pInvoiceBlueDetail.setGoodsTotalPrice(invoiceDetail.getGoodsTotalPrice());//开票明细记录 金额
                pInvoiceBlueDetail.setGoodsTaxRate(invoiceDetail.getGoodsTaxRate());//开票明细记录 税率
                pInvoiceBlueDetail.setPriceTaxMark(FinalUtil.INVLID_PRICE_TAX_MARK);//含税标志：默认1
                pInvoiceBlueDetail.setPreferential(invoiceDetail.getPreferentialMark());//是否使用优惠政策
                pInvoiceBlueDetail.setPaymentDate(invoiceDetail.getPaymentDate());//缴费时间
                pInvoiceBlueDetail.setGoodsTotalTax(invoiceDetail.getGoodsTotalTax());//税额
                pInvoiceBlueDetail.setFreeTaxMark(invoiceDetail.getFreeTaxMark());//零税率标识：空代表无， 1 出口免税和其他免税优惠政策，2 不征增值税， 3 普通零税率”
                pInvoiceBlueDetailList.add(pInvoiceBlueDetail);
            }
            // 1、保存蓝票开票记录
            pInvoiceBlueService.save(pInvoiceBlue, pInvoiceBlueDetailList);
            // 2、调用百望开票接口开票
            //如果是立即开票，调用立即开票接口
            if(FinalUtil.INVOICE_IMMEDIATE_FLG.equals(requestJson.getImmediatelyFlg())){
                //调用立即开票接口
                PInvoiceBlue pInvoiceBlueRet = callOut_invOpenOutController.invoiceBlueFromImmRequest(pInvoiceBlue);
                if (pInvoiceBlueRet != null) {
                    //  3、调用百望开票结果查询接口，查询开票结果
                    InvoiceQueryResponse response = callOut_invoiceQueryOutController.invoiceBlueQueryOut(pInvoiceBlueRet);
                    //返回结果
                    if(response == null){
                        return new ResponseJson(ErrorInfoEnum.FAIL_QUERY, "发票"+pInvoiceBlueRet.getGuid()).toString();
                    }
                    //  4、开电子发票时，调研百望电子发票查询接口，获取电子发票URL
                    String strUrl = null;
                    if(FinalUtil.INVOICE_TYPE_CODE_026.equals(pInvoiceBlue.getInvoiceTypeCode())){
                         strUrl =  callOut_invPdfOutController.invPdfOut(pInvoiceBlue);
                    }
                    //生成返回结果集
                    JSONObject RetJsonObject =callOut_invOpenRetInfoOutController.invOpenRetBlueInfoOut(response,pInvoiceBlue,strUrl);
                    JSONObject RetJson = new JSONObject();
                    RetJson.put("errcode", "0000");
                    RetJson.put("errmsg", "处理成功");
                    RetJson.put("data", RetJsonObject);
                    return RetJson.toString();
                }
            }
        } catch (Exception e) {
            retJson = new ResponseJson(ErrorInfoEnum.FAIL_OPEN, e.getMessage());
        }
        return retJson.toString();
    }
}
